package com.rise.remi.network;

import com.rise.remi.core.Core_v1;
import com.rise.remi.items.Item;
import com.rise.remi.items.TempNameSwitch;
import com.rise.remi.main.Main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import lombok.Setter;

/**
 *
 * @author remi Класс сети, в котором происходит обработка всех событий,
 * полученных с другой стороны. Суперкласс для Client и Server.
 * @see Client
 * @see Server
 */
public class Network {
    protected static final int SERVER_PORT = 7777;
    @Setter protected static String SERVER_IP = "";

    protected ServerSocket serverSocket;
    protected Socket socket;
    protected DataOutputStream out;
    protected DataInputStream in;
    private long lastTime = System.currentTimeMillis();

    //
    //private Server server = new Server();
    //private Client client = new Client();
    private boolean isServer;

    public void enableClient() {
        isServer = false;
    }

    public void enableServer() {
        isServer = true;
    }

    public void sendData(NetworkMessage message) {
        //if (!message.isEmpty()) {
        try {
            out.writeUTF(message.getType() + message.getBody());
        } catch (IOException ex) {
        }
        //}
    }

    public void getData() throws Exception {
        String msgBody = in.readUTF();

        //1 - первый символ в сообщении обозначает тип сообщения
        //всего типов 10, все указаны в классе NetworkMessage
        int msgType = Integer.parseInt(msgBody.substring(0, 1));
        msgBody = msgBody.substring(1);

        switch (msgType) {
            case NetworkMessage.CHAT_MESSAGE:
                writeTime();
                System.out.println("DING-DONG! You have recieved a message.");
                Main.addToChat(Main.getCore().getFriend().getName() + ": " + msgBody);
                break;
            case NetworkMessage.PLAYER_MOVEMENT:
                moveFriend(msgBody);
                break;
            case NetworkMessage.SEND_ITEM:
                processingItem(msgBody);
                break;
            case NetworkMessage.REMOVE_ITEM:
                removeItem(msgBody);
                break;
            case NetworkMessage.PING:
                lastTime = System.currentTimeMillis();
                writeTime();
                System.out.println("Pinged.");
                break;
        }

        //check ping
        if (System.currentTimeMillis() - lastTime > 30000) {
            System.out.println("ping timeout");
            //System.exit(0);
        }
    }

    private void moveFriend(String msgBody) {
        if ("u".equalsIgnoreCase(msgBody)) {
            Core_v1.getInstance().getFriend().moveUp();
        }
        if ("d".equalsIgnoreCase(msgBody)) {
            Core_v1.getInstance().getFriend().moveDown();
        }
        if ("l".equalsIgnoreCase(msgBody)) {
            Core_v1.getInstance().getFriend().moveLeft();
        }
        if ("r".equalsIgnoreCase(msgBody)) {
            Core_v1.getInstance().getFriend().moveRight();
        }
    }

    private void processingItem(String msgBody) {
        //разбираем сообщение на куски
        String[] pieces = msgBody.split(":");
        int id = Integer.parseInt(pieces[0]);
        int x = Integer.parseInt(pieces[1]);
        int y = Integer.parseInt(pieces[2]);

        //System.out.println("" + x + ":" + y);
        synchronized (Main.getCore().getWorld().getItems()) {
            Main.getCore().getWorld().getItems().add(new Item(TempNameSwitch.switchName(id) + " (id: " + id + ")", id, x, y));
            //System.out.println("" + y + ":" + y);
        }
    }

    private void removeItem(String msgBody) {
        synchronized (Main.getCore().getWorld().getItems()) {
            Main.getCore().getWorld().getItems().remove(Integer.parseInt(msgBody));
        }
    }

    private String[] parseMsgBody(String msgBody) {
        String[] pieces = msgBody.split(":");
        return pieces;
    }

    private void writeTime() {
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        System.out.print("[" + dateFormat.format(date) + "] ");
    }
}
